package com.yupi.springbootinit.bimq;

import com.baidubce.appbuilder.base.exception.AppBuilderServerException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.exception.ThrowUtils;
import com.yupi.springbootinit.model.entity.Chart;
import com.yupi.springbootinit.service.ChartService;
import com.yupi.springbootinit.service.impl.BaiDuAiManager;
import com.yupi.springbootinit.utils.ExcelUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.retry.annotation.Recover;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;

import static com.yupi.springbootinit.bimq.BiMqConstant.BI_QUEUE_NAME;


@Component
@Slf4j
public class BiMyMessageConsumer {

    @Resource
    private ChartService chartService;

    @SneakyThrows
    @RabbitListener(queues = {BI_QUEUE_NAME} ,ackMode = "MANUAL")
    public void receiveMessage(String message, Channel channel,@Header(AmqpHeaders.DELIVERY_TAG)long deliveryTag) throws Exception {
        //ThrowUtils.throwIf(StringUtils.isBlank(message),ErrorCode.PARAMS_ERROR,"mq接收到的信息为null");
        if(StringUtils.isBlank(message)){
            // 如果更新失败，拒绝当前消息，让消息重新进入队列
            channel.basicNack(deliveryTag,false,false);
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"mq接收到的信息为null");
        }
        log.info("receive message:{}",message);
        long chartId = Long.parseLong(message);
        Chart chart = chartService.getById(chartId);
        //ThrowUtils.throwIf(chart == null,ErrorCode.NOT_FOUND_ERROR,"chart数据查询失败");
        if(chart == null){
            channel.basicNack(deliveryTag,false,false);
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR,"chart数据查询数据不存在");
        }
        String[] strings = null;
        Chart updateChart = new Chart();
        updateChart.setId(chartId);
        updateChart.setStatus("running");
        boolean b = chartService.updateById(updateChart);
        //ThrowUtils.throwIf(!b, ErrorCode.PARAMS_ERROR, "执行状态更改失败");
        if(!b){
            channel.basicNack(deliveryTag,false,false);
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"执行状态更改失败");
        }
        try {
            String result = BaiDuAiManager.BaiDuAiChart(userInput(chart));
            strings = result.split("【【【【【");
            if(strings.length < 3){
                throw new BusinessException(ErrorCode.OPERATION_ERROR,"生成不符合规则");
            }
        } catch (IOException | AppBuilderServerException e) {
            log.error("异步生成{}", e.getMessage());
        }
        //ThrowUtils.throwIf(strings == null, ErrorCode.PARAMS_ERROR, "结论图表为空");
        if(strings == null){
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"AI生成失败");
        }
        // 提取 data 部分
        String option = strings[1].split("【【【【【")[0].trim();
        // 提取 conclusion 部分
        String conclusion = strings[2].trim();
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = null;
        try {
            jsonNode = objectMapper.readTree(option);
        } catch (JsonProcessingException e) {
            log.error("json 格式更改失败");
        }
        assert jsonNode != null;
        String chartOption = jsonNode.toPrettyString();
        // 得到结果 状态改为 succeed
        Chart updateChartResult = new Chart();
        updateChartResult.setId(chart.getId());
        updateChartResult.setStatus("succeed");
        updateChartResult.setGenChart(chartOption);
        updateChartResult.setGenResult(conclusion);
        boolean bl = chartService.updateById(updateChartResult);
        //ThrowUtils.throwIf(!bl, ErrorCode.PARAMS_ERROR, "执行状态更改失败");
        if(!bl){
            channel.basicNack(deliveryTag,false,false);
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"执行状态更改失败");
        }
        channel.basicAck(deliveryTag,false);
    }

    private String userInput(Chart chart) {
        String goal = chart.getGoal();
        String chartType = chart.getChartType();
        String csvData = chart.getChartData();
        StringBuilder builder = new StringBuilder();
        // 预设角色
        builder.append("你是一个数据分析师，接下来我给你我的分析目标和原始数据，请告诉我你的结论").append("\n");
        //分析目标
        builder.append("分析需求：").append("\n");
        String useGoal = goal;
        if (StringUtils.isNotBlank(chartType)) {
            useGoal += ",请使用" + chartType;
        }
        builder.append(useGoal).append("\n");
        // 压缩后的数据
        builder.append("数据:").append(csvData).append("\n");
        return builder.toString();
    }
}
